package com.dog.basics.api.security;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dog.basics.bean.model.common.DogUser;
import com.dog.basics.bean.model.common.DogUserConnect;
import com.dog.basics.common.annotation.RedisLock;
import com.dog.basics.dao.common.DogUserConnectMapper;
import com.dog.basics.dao.sys.SysUserMapper;
import com.dog.basics.security.dao.AppConnectMapper;
import com.dog.basics.security.enums.App;
import com.dog.basics.security.exception.UsernameNotFoundExceptionBase;
import com.dog.basics.security.model.AppConnect;
import com.dog.basics.security.service.DogUserDetailsService;
import com.dog.basics.service.common.IDogUserConnectService;
import com.dog.basics.service.common.IDogUserService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户详细信息
 *
 * @author
 */
@Slf4j
@Service
@AllArgsConstructor
public class DogUserServiceImpl implements DogUserDetailsService {
    private final DogUserConnectMapper dogUserConnectMapper;
    private final AppConnectMapper appConnectMapper;
    private final IDogUserConnectService dogUserConnectService;
    private final IDogUserService cljgUserService;
    private final SysUserMapper sysUserMapper;


    @Override
    @SneakyThrows
    public com.dog.basics.security.service.DogUser loadUserByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            throw new UsernameNotFoundExceptionBase("该用户不存在");
        }
        DogUser user = cljgUserService.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, username));
        return restructureUserDogUser(user, username);
    }

    /**
     * 获取前端登陆的用户信息
     *
     * @param app
     * @param bizUserId openId
     * @return UserDetails
     * @throws UsernameNotFoundExceptionBase
     */
    @Override
    public com.dog.basics.security.service.DogUser loadUserByAppIdAndBizUserId(App app, String bizUserId) {

        //  User user = userMapper.getUserByBizUserId(app.value(), bizUserId);
        //   return restructureUserDogUser(user, bizUserId);
        return null;
    }

    /**
     * 手机号或者邮箱密码登录
     *
     * @param code 所登陆的应用
     * @return UserDetails
     * @throws UsernameNotFoundExceptionBase
     */
    @Override
    public com.dog.basics.security.service.DogUser loadUserBypasswordOrEmail(String code) {
        //先判断手机号
        Boolean mobileFlage = Validator.isMobile(code);
        //如果true就是手机号注册
        if (mobileFlage) {
            DogUser user = cljgUserService.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, code));
            return restructureUserDogUser(user, code);
        } else {
            DogUser user = cljgUserService.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMail, code));
            return restructureUserDogUser(user, code);
        }
    }

    @Override
    public com.dog.basics.security.service.DogUser loadUserByWxPhone(String mobile, String openId, String uuind, Integer from) {
        if (StrUtil.isBlank(mobile)) {
            throw new UsernameNotFoundExceptionBase("该用户不存在");
        }

        DogUser user = cljgUserService.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, mobile));
        if(ObjectUtil.isNotNull(user)){
            return restructureUserDogUser(user, openId);
        }else{
            this.insertUserIfNecessaryPhone(mobile,uuind,openId,1,from);
            return null;
        }


    }

    @Transactional(rollbackFor = Exception.class)
    public void insertUserIfNecessaryPhone(String mobile, String unionId, String openId, Integer type, Integer from) {
        // 进入锁后再重新判断一遍用户是否创建
        DogUser user = cljgUserService.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, mobile));
        //先查询uuid本身存在不
        List<DogUserConnect> list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getUnionId, unionId));
        if (ObjectUtil.isNotNull(user)) {
            if (CollUtil.isNotEmpty(list)) {
                DogUserConnect dogUserConnect = list.get(0);
                if (from == 0) {
                    dogUserConnect.setMiniOpenid(openId);
                } else {
                    dogUserConnect.setMiniShopOpenid(openId);
                }
                dogUserConnectMapper.updateById(dogUserConnect);

            } else {
                DogUserConnect dogUserConnect = new DogUserConnect();
                dogUserConnect.setUserId(user.getUserId());
                dogUserConnect.setCreateTime(DateUtil.currentSeconds());
                dogUserConnect.setCreateBy(user.getUserId());
                if (type == 0) {
                    dogUserConnect.setGzhOpenid(openId);
                } else {
                    if (from == 0) {
                        dogUserConnect.setMiniOpenid(openId);
                    } else {
                        dogUserConnect.setMiniShopOpenid(openId);
                    }
                    dogUserConnect.setUnionId(unionId);
                }
                dogUserConnectMapper.insert(dogUserConnect);

            }
        } else {
            user = new DogUser();
            user.setModifyTime(DateUtil.currentSeconds());
            user.setUserRegtime(DateUtil.currentSeconds());
            //user.getLockFlag(0);
            user.setLoginPassword("-1");
            user.setPic("-1");
            user.setUserMobile(mobile);
            cljgUserService.save(user);
            DogUserConnect dogUserConnect = new DogUserConnect();
            dogUserConnect.setUserId(user.getUserId());
            dogUserConnect.setCreateTime(DateUtil.currentSeconds());
            dogUserConnect.setCreateBy(user.getUserId());
            if (type == 0) {
                dogUserConnect.setGzhOpenid(openId);
            } else {
                if (from == 0) {
                    dogUserConnect.setMiniOpenid(openId);
                } else {
                    dogUserConnect.setMiniShopOpenid(openId);
                }
                dogUserConnect.setUnionId(unionId);
            }
            dogUserConnectMapper.insert(dogUserConnect);
        }


    }


    @Override
    public com.dog.basics.security.service.DogUser loadUserByAppOpenId(String code) {
        List<DogUserConnect> list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getAppOpenid, code));
        if (CollUtil.isNotEmpty(list)) {
            DogUser user = cljgUserService.getById(list.get(0).getUserId());
            return restructureUserDogUser(user, code);
        } else {
            com.dog.basics.security.service.DogUser DogUser = new com.dog.basics.security.service.DogUser(-1L, "", Boolean.TRUE, "", 1);
            return DogUser;
        }
    }


    @Override
    public com.dog.basics.security.service.DogUser loadUserByWxOpenId(String openId, Integer type, String unionId, Integer from) {
        //查询第三方表Id
        List<DogUserConnect> list = CollUtil.newArrayList();
        if (type == 0) {
            list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getGzhOpenid, openId));
        } else {
            if (from == 0) {
                list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getUnionId, unionId).eq(DogUserConnect::getMiniOpenid, openId));
            } else {
                list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getUnionId, unionId).eq(DogUserConnect::getMiniShopOpenid, openId));
            }

        }

        if (CollUtil.isNotEmpty(list)) {
            DogUser user = cljgUserService.getById(list.get(0).getUserId());
            return restructureUserDogUser(user, openId);
        } else {
            this.insertUserIfNecessaryNew(unionId, openId, type, from);
            return null;
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void insertUserIfNecessaryNew(String unionId, String openId, Integer type, Integer from) {
        //先查询uuid本身存在不
        List<DogUserConnect> list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getUnionId, unionId));
        if (CollUtil.isNotEmpty(list)) {
            DogUserConnect dogUserConnect = list.get(0);
            DogUser user = cljgUserService.getById(dogUserConnect.getUserId());
            if (ObjectUtil.isNotNull(user)) {
                if (from == 0) {
                    dogUserConnect.setMiniOpenid(openId);
                } else {
                    dogUserConnect.setMiniShopOpenid(openId);
                }
                dogUserConnectMapper.updateById(dogUserConnect);
            } else {
                throw new UsernameNotFoundExceptionBase("该用户不存在");
            }
        } else {
            DogUser user = new DogUser();
            user.setModifyTime(DateUtil.currentSeconds());
            user.setUserRegtime(DateUtil.currentSeconds());
            //user.getLockFlag(0);
            user.setLoginPassword("-1");
            user.setPic("-1");
            //user.setUserMobile(phone);
            cljgUserService.save(user);
            DogUserConnect dogUserConnect = new DogUserConnect();
            dogUserConnect.setUserId(user.getUserId());
            dogUserConnect.setCreateTime(DateUtil.currentSeconds());
            dogUserConnect.setCreateBy(user.getUserId());
            if (type == 0) {
                dogUserConnect.setGzhOpenid(openId);
            } else {
                if (from == 0) {
                    dogUserConnect.setMiniOpenid(openId);
                } else {
                    dogUserConnect.setMiniShopOpenid(openId);
                }
                dogUserConnect.setUnionId(unionId);
            }
            dogUserConnectMapper.insert(dogUserConnect);

        }


    }


    @Override
    public com.dog.basics.security.service.DogUser loadUserByminiOpenId(String code) {
        //查询第三方表Id
        List<DogUserConnect> list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getMiniOpenid, code));
        if (CollUtil.isNotEmpty(list)) {
            DogUser user = cljgUserService.getById(list.get(0).getUserId());
            return restructureUserDogUser(user, code);
        } else {
            com.dog.basics.security.service.DogUser DogUser = new com.dog.basics.security.service.DogUser(-1L, "", Boolean.TRUE, "", 1);
            return DogUser;
        }
    }


    /**
     * 获取用户重构
     *
     * @param user
     * @param userNameOrOppId
     * @return guonh 2019年12月20日
     */
    private com.dog.basics.security.service.DogUser restructureUserDogUser(DogUser user, String userNameOrOppId) {
        if (user == null) {
            throw new UsernameNotFoundExceptionBase("该用户不存在");
        }
        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        com.dog.basics.security.service.DogUser DogUser = new com.dog.basics.security.service.DogUser(user.getUserId(), userNameOrOppId, user.getLockFlag() == 0,
                user.getLoginPassword(), 0);
        DogUser.setName(name);
        DogUser.setPic(user.getPic());
        // boolean competitionArea = (ObjectUtil.isNull(user.getPartnerUserId()) || user.getPartnerUserId().equals(-1L)) ? false : true;
        //  DogUser.setCompetitionArea(competitionArea);
        return DogUser;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @RedisLock(lockName = "insertUser", key = " 'addUser:' + #phone")
    @Caching(evict = {@CacheEvict(cacheNames = "dog_user", key = "#phone"),})
    public void insertUserIfNecessary(String phone, String openId, Integer type) {
        // 进入锁后再重新判断一遍用户是否创建
        DogUser user = cljgUserService.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, phone));
        if (ObjectUtil.isNull(user)) {
            user = new DogUser();
            user.setModifyTime(DateUtil.currentSeconds());
            user.setUserRegtime(DateUtil.currentSeconds());
            //user.getLockFlag(0);
            user.setLoginPassword("-1");
            user.setPic("-1");
            user.setUserMobile(phone);
            cljgUserService.save(user);
            DogUserConnect dogUserConnect = new DogUserConnect();
            dogUserConnect.setUserId(user.getUserId());
            dogUserConnect.setCreateTime(DateUtil.currentSeconds());
            dogUserConnect.setCreateBy(user.getUserId());
            dogUserConnectMapper.insert(dogUserConnect);
        }
        // 判断并且绑定微信信息
        if (StrUtil.isNotBlank(openId)) {
            DogUserConnect dogUserConnect = null;
            //判断是否有open绑定信息
            List<DogUserConnect> appConnects = dogUserConnectMapper.selectList(
                    Wrappers.<DogUserConnect>lambdaQuery()
                            .eq(DogUserConnect::getUserId, user.getUserId()));
            if (CollUtil.isNotEmpty(appConnects)) {
                dogUserConnect = appConnects.get(0);
                if (type == 0) {
                    dogUserConnect.setGzhOpenid(openId);
                } else {
                    dogUserConnect.setMiniOpenid(openId);
                }
                dogUserConnectMapper.updateById(dogUserConnect);
            }

        }

    }

    @Override
    public void insertUserConnect(AppConnect appConnect) {
        // 判断是否存在
        List<AppConnect> appConnects = appConnectMapper.selectList(
                Wrappers.<AppConnect>lambdaQuery().eq(AppConnect::getAppId, appConnect.getAppId())
                        .eq(AppConnect::getBizUserId, appConnect.getBizUserId()));
        // 无则添加 ,有则不添加
        if (CollUtil.isEmpty(appConnects)) {
            appConnect.setUserId(-1L);
            appConnectMapper.insert(appConnect);
        }
    }


}
